home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / Papers / C++ Exceptions / µShell / UI Classes / Windows / Window.cp next >
Encoding:
Text File  |  1996-06-09  |  24.8 KB  |  911 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Window.cp
  3.  
  4.     Contains:    Implementation of TWindow, a base class which provides a
  5.                 framework for building way-cool windows which even John
  6.                 Sullivan would be happy with. Floating windows and “smart
  7.                 zooming” algorithms are based on code samples provided by
  8.                 Dean Yu. Tim Craycroft, the guy making the window manager
  9.                 do all this work for you has also been a great help.
  10.                 
  11.     Written by: Dave Falkenburg
  12.  
  13.     Copyright:    © 1993-1995 by Dave Falkenburg, all rights reserved.
  14.  
  15.     Change History (most recent first):
  16.     
  17.         <14>     1/24/95    DRF        DoMenuSelection now returns a Boolean. Added some default
  18.                                     behavior for handling the close menu item-- this will change
  19.                                     when we make some things recordable.
  20.         <13>     1/20/95    DRF        Fix the “calling DisposeWindow on DialogPtr” problem reported by
  21.                                     Gary Powell @ Adobe by adding a cheezy flag that TWindow
  22.                                     initializes, but TDialogWindow slams. In TWindow::Close, we
  23.                                     check this flag and call DisposeDialog instead of DisposeWindow,
  24.                                     surely preventing memory leaks for complex dialogs.
  25.         <12>      1/3/95    DRF        Add Nitin’s changes for Drag handling: a ClickAndDrag method.
  26.         <11>      1/3/95    DRF        DoMenuCommand now returns a Boolean. Also got rid of
  27.                                     conditionals for ClipAbove: by the time this gets to print
  28.                                     everyone should be using Universal Headers 2.0.
  29.         <10>     12/6/94    DRF        Rolled in David Den Boer’s fixes. Also add the conditionals for
  30.                                     newest universal headers again.
  31.          <9>    11/23/94    DRF        Bite the bullet just require the latest universal headers
  32.          <8>    11/17/94    DRF        Add casts for CFront & PPCC. Also dealt with the change to
  33.                                     ClipAbove in the latest universal headers.
  34.          <7>    11/12/94    DRF        Added AdjustMenusBeforeMenuSelection.
  35.          <6>     11/8/94    DRF        Add some better menu handling methods.
  36.          <5>     9/27/94    DRF         AppLib.h is now Sprocket.h
  37.          <4>      9/9/94    DRF        Reorganized headers and removed redundant #includes.
  38.          <3>      9/4/94    DRF        Added DrawJustTheGrowIcon.
  39.          <2>     8/27/94    DRF        In TWindow::Close, call window’s (de)Activate method before
  40.                                     closing so that menus can be properly updated.
  41.     
  42.     To Do:        Make sure invisible windows can be created & managed
  43.                 Handle modal windows as another class of windows
  44.                 Fix activate bugs when showing and hiding windows
  45.                 Window positioning methods (getters and setters)
  46.                 Display Manager support
  47.                 Changes to support AEObject model
  48.  */
  49.  
  50. #include "Window.h"
  51. #include "WindowManager.h"
  52.  
  53. #include "Exceptions.h"
  54. #include "ForegroundApplication.h"
  55. #include "Sprocket.h"
  56. #include "StringUtil.h"
  57.  
  58. #include <Script.h>        //    for GetMBarHeight()
  59. #include <LowMem.h>        //    for LMGetWindowList()
  60. #include <AEObjects.h>
  61. #include <AEPackObject.h>
  62.  
  63. extern WindowManager gWindowManager;
  64.  
  65. DragTrackingHandler    TWindow::fgDragTrackingHandler = nil;
  66. DragReceiveHandler    TWindow::fgDragReceiveHandler = nil;
  67. //RgnHandle            TWindow::fgScratchRgn = nil;
  68. //short                TWindow::fgNumWindows = 0;
  69.  
  70.  
  71. static void            HiliteShowHideFloatingWindows(Boolean hiliting,Boolean hiding);
  72. static void            FindScreenRectWithLargestPartOfWindow(WindowRef aWindow,Rect *theBestScreenRect, GDHandle * theBestDevice);
  73. static pascal void    CalculateWindowAreaOnDevice(short depth,short deviceFlags,GDHandle targetDevice,long userData);
  74.  
  75. //--------------------------------------------------------------------------------
  76. inline Point& topLeft(Rect& r)
  77. {
  78.     return *(Point*) (&r.top);
  79. }
  80.  
  81.  
  82. //--------------------------------------------------------------------------------
  83. inline Point& botRight(Rect& r)
  84. {
  85.     return *(Point*) (&r.bottom);
  86. }
  87.  
  88.  
  89. //--------------------------------------------------------------------------------
  90. inline void LocalToGlobal(Rect* r)
  91. {
  92.     ::LocalToGlobal(&topLeft(*r));
  93.     ::LocalToGlobal(&botRight(*r));
  94. }
  95.  
  96.  
  97. //--------------------------------------------------------------------------------
  98. inline void GlobalToLocal(Rect* r)
  99. {
  100.     ::GlobalToLocal(&topLeft(*r));
  101.     ::GlobalToLocal(&botRight(*r));
  102. }
  103.  
  104. int    WithModalDialogHilite::fgNestLevel = 0;
  105.     
  106. WithModalDialogHilite::WithModalDialogHilite()
  107. {
  108.     if (fgNestLevel++ <= 0)
  109.         TWindow::BeginModalDialog();
  110. }
  111.  
  112. WithModalDialogHilite::~WithModalDialogHilite()
  113. {
  114.     if (--fgNestLevel <= 0)
  115.         TWindow::EndModalDialog();
  116. }
  117.  
  118. WindowRef TWindow::GetNewWindow(
  119.     short        windowID,
  120.     WindowRef    behind,
  121.     WindowLayer    layer)
  122. {
  123.     return gWindowManager.GetNewWindow(windowID, behind, layer);
  124. }
  125.  
  126. WindowRef TWindow::NewWindow(
  127.     const Rect &boundsRect,
  128.     ConstStr255Param title,
  129.     Boolean visible,
  130.     short theProc,
  131.     WindowRef behind,
  132.     Boolean goAwayFlag,
  133.     long refCon,
  134.     WindowLayer layer)
  135. {
  136.     return gWindowManager.NewWindow(boundsRect, title, visible, theProc, behind, goAwayFlag, refCon, layer);
  137. }
  138.  
  139. void TWindow::SuspendApplication(void)
  140. {
  141.     gWindowManager.SuspendApplication();
  142. }
  143.  
  144. void TWindow::ResumeApplication(void)
  145. {
  146.     gWindowManager.ResumeApplication();
  147. }
  148.  
  149. void TWindow::BeginModalDialog(void)
  150. {
  151.     gWindowManager.BeginModalDialog();
  152. }
  153.  
  154. void TWindow::EndModalDialog(void)
  155. {
  156.     gWindowManager.EndModalDialog();
  157. }
  158.  
  159. //--------------------------------------------------------------------------------
  160. TWindow::TWindow(WindowRef aWindowRef)
  161. :    fWindow(aWindowRef)
  162. {
  163.     FailNil(aWindowRef);
  164.  
  165.     fNextEventDispatcher    = gApplication;
  166.  
  167.     SetWRefCon(aWindowRef,(long) this);
  168.  
  169.     if (fgDragTrackingHandler == nil)
  170.         fgDragTrackingHandler = NewDragTrackingHandlerProc(TWindow::CallWindowDragTrackingHandler);
  171.     if (fgDragReceiveHandler == nil)
  172.         fgDragReceiveHandler = NewDragReceiveHandlerProc(TWindow::CallWindowDragReceiveHandler);
  173.  
  174.     InstallTrackingHandler(fgDragTrackingHandler, aWindowRef, this);
  175.     InstallReceiveHandler(fgDragReceiveHandler, aWindowRef, this);
  176. }
  177.  
  178.  
  179. //--------------------------------------------------------------------------------
  180. void TWindow::IWindow()
  181. {
  182. }
  183.  
  184. //--------------------------------------------------------------------------------
  185. void TWindow::Dispose()
  186. {
  187.     if (fWindow)
  188.     {
  189.         OSErr err1 = RemoveTrackingHandler(fgDragTrackingHandler, fWindow);
  190.         OSErr err2 = RemoveReceiveHandler(fgDragReceiveHandler, fWindow);
  191.         
  192.         gWindowManager.DisposeWindow(fWindow);
  193.  
  194.         fWindow = nil;
  195.     }
  196. }
  197.  
  198. //--------------------------------------------------------------------------------
  199. TWindow::~TWindow()
  200. {
  201.     if (fWindow)
  202.     {
  203.         this->Dispose();
  204.     }
  205. }
  206.  
  207.  
  208. //--------------------------------------------------------------------------------
  209. Boolean TWindow::EventFilter(EventRecord * /* theEvent */)
  210. {
  211.     return false;
  212. }
  213.  
  214.  
  215. //--------------------------------------------------------------------------------
  216. void TWindow::Select(void)
  217. {
  218.     gWindowManager.SelectWindow(fWindow);
  219. }
  220.  
  221.  
  222. //--------------------------------------------------------------------------------
  223. void TWindow::ShowHide(Boolean showFlag)
  224. {
  225.     //    Here we need the “::” in front of ShowHide to indicate we are calling
  226.     //    the global function, and not the method ShowHide. Unintended recursion
  227.     //    can do bad things to the unsuspecting programmer.
  228.     
  229.     //    Some C++ programmers would always prepend the “::” on function calls.
  230.     
  231.     ::ShowHide(fWindow,showFlag);
  232. }
  233.     
  234.  
  235. //--------------------------------------------------------------------------------
  236. // by default do nothing
  237. void TWindow::AdjustCursor(Point /*where*/)
  238. {
  239. }
  240.  
  241.  
  242. //--------------------------------------------------------------------------------
  243. // when we become active, we want to get events
  244. void TWindow::Activate()
  245. {
  246.     SetCurrentEventDispatcher(*this);
  247. }
  248.  
  249.  
  250. //--------------------------------------------------------------------------------
  251. // when we become inactive, we no longer want to get events
  252. void TWindow::Deactivate()
  253. {
  254.     RemoveEventDispatcher(*this);    
  255. }    
  256.  
  257.  
  258. //--------------------------------------------------------------------------------
  259. void TWindow::Draw(void)
  260. {
  261. }
  262.     
  263.  
  264. //--------------------------------------------------------------------------------
  265. void TWindow::DrawGrowIcon(void)
  266. {
  267.     gWindowManager.DrawWindowGrowIcon(fWindow);
  268. }
  269.  
  270. //--------------------------------------------------------------------------------
  271. // by default do nothing
  272. void TWindow::Click(EventRecord * /* anEvent */)
  273. {
  274. }
  275.  
  276.  
  277. //--------------------------------------------------------------------------------
  278. // by default do nothing
  279. void TWindow::KeyDown(EventRecord * /*anEvent*/)
  280. {
  281. }
  282.  
  283.  
  284. //--------------------------------------------------------------------------------
  285. Rect TWindow::GetGrowSizeRect(void)
  286. {
  287.     Rect limits;
  288.  
  289.     limits.top      = limits.left  = kMinimumWindowSize;
  290.     limits.bottom = limits.right = 32000;
  291.     
  292.     return limits;
  293. }
  294.  
  295.  
  296. //--------------------------------------------------------------------------------
  297. // by default do nothing
  298. void TWindow::AdjustForNewWindowSize(Rect * /* oldRect */, Rect * /* newSize */)
  299. {
  300. }
  301.  
  302.  
  303. //--------------------------------------------------------------------------------
  304. Rect TWindow::GetBounds(void) const
  305. {
  306.     GrafPtr oldPort;
  307.     Rect bounds = GetWindowBounds(fWindow);
  308.  
  309.     GetPort(&oldPort);
  310.     SetPortWindowPort(fWindow);
  311.     LocalToGlobal(&bounds);
  312.     SetPort(oldPort);
  313.  
  314.     return bounds;
  315. }
  316.  
  317.  
  318. //--------------------------------------------------------------------------------
  319. Boolean TWindow::HasCloseBox(void) const
  320. {
  321.     return GetWindowGoAwayFlag(fWindow);
  322. }
  323.  
  324.  
  325. //--------------------------------------------------------------------------------
  326. // Why isn't this defined in Windows.h ??
  327. Boolean GetWindowTitleBar(WindowRef fWindow);
  328. Boolean GetWindowTitleBar(WindowRef fWindow)
  329. {
  330.     short winKind = GetWVariant(fWindow);
  331.     
  332.     // really ugly ... got a better idea ??  (could look at contRgn vs. strucRgn)
  333.     return ! ((winKind == dBoxProc) || (winKind == plainDBox) || (winKind == altDBoxProc));
  334. }
  335.  
  336. //--------------------------------------------------------------------------------
  337. Boolean TWindow::HasTitleBar(void) const
  338. {
  339.     return GetWindowTitleBar(fWindow);
  340. }
  341.  
  342.  
  343. //--------------------------------------------------------------------------------
  344. long TWindow::GetIndex(void) const
  345. {
  346.     return gWindowManager.GetWindowIndex(fWindow, kNormalWindowLayer);
  347. }
  348.  
  349.  
  350. //--------------------------------------------------------------------------------
  351. Boolean TWindow::IsFloating(void) const
  352. {
  353.     return gWindowManager.IsWindowFloating(fWindow);
  354. }
  355.  
  356.  
  357. //--------------------------------------------------------------------------------
  358. Boolean TWindow::IsModal(void) const
  359. {
  360.     return gWindowManager.IsWindowModal(fWindow);
  361. }
  362.  
  363.  
  364. //--------------------------------------------------------------------------------
  365. // Why isn't this defined in Windows.h ??
  366. Boolean GetWindowSizeFlag(WindowRef fWindow);
  367. Boolean GetWindowSizeFlag(WindowRef fWindow)
  368. {
  369.     short winKind = GetWVariant(fWindow);
  370.     
  371.     // really ugly ... got a better idea ??
  372.     return ((winKind == documentProc) || (winKind == zoomDocProc));
  373. }
  374.  
  375. //--------------------------------------------------------------------------------
  376. Boolean TWindow::IsResizable(void) const
  377. {
  378.     return GetWindowSizeFlag(fWindow);
  379. }
  380.  
  381.  
  382. //--------------------------------------------------------------------------------
  383. Boolean TWindow::IsZoomable(void) const
  384. {
  385.     return GetWindowZoomFlag(fWindow);
  386. }
  387.  
  388.  
  389. //--------------------------------------------------------------------------------
  390. // it would be nice to have a cleaner way to do this
  391. Boolean TWindow::IsZoomed(void) const
  392. {
  393.     GrafPtr    oldPort;
  394.     Rect     zoomedRect;
  395.     Rect     bounds = GetWindowBounds(fWindow);
  396.  
  397.     GetPort(&oldPort);
  398.     SetPortWindowPort(fWindow);
  399.     LocalToGlobal(&bounds);
  400.     SetPort(oldPort);
  401.  
  402.     GetWindowStandardState (fWindow, &zoomedRect);
  403.     return EqualRect(&bounds, &zoomedRect);
  404. }
  405.  
  406.  
  407. //--------------------------------------------------------------------------------
  408. Boolean TWindow::SetZoomed(Boolean zoomed)
  409. {
  410.     // is this window zoomable ??
  411.     if (!this->TWindow::IsZoomable())
  412.     {
  413.         Fail(errAEEventNotHandled);
  414.         return false;
  415.     }
  416.  
  417.     // if it is, zoom Out or zoom In as the event requested 
  418.     if (zoomed)
  419.         gWindowManager.ZoomWindow(fWindow, inZoomOut, this->GetPerfectWindowSize());
  420.     else
  421.         gWindowManager.ZoomWindow(fWindow, inZoomIn, this->GetPerfectWindowSize());
  422.     return true;        
  423. }
  424.  
  425.  
  426. //--------------------------------------------------------------------------------
  427. Boolean TWindow::IsVisible(void) const
  428. {
  429.     return gWindowManager.IsWindowVisible(fWindow);
  430. }
  431.  
  432.  
  433. //--------------------------------------------------------------------------------
  434. Rect TWindow::SetBounds(Rect r)
  435. {
  436.     Rect oldBounds = GetWindowBounds(fWindow);
  437.     
  438.     gWindowManager.SetWindowBounds(fWindow, r);
  439.  
  440.     return oldBounds;
  441. }
  442.  
  443.  
  444. //--------------------------------------------------------------------------------
  445. long TWindow::SetIndex(long index)
  446. {
  447.     // TO DO: move the window to an arbitrary position
  448.     // note that we need to handle negative indices
  449.     // and make sure window stays in the right layer
  450.     
  451.     // Open Issue: Do floating/modal windows count in 
  452.     // index?
  453.     return index;
  454. }
  455.  
  456.  
  457. //--------------------------------------------------------------------------------
  458. Boolean TWindow::SetVisible(Boolean show)
  459. {
  460.     Boolean result = gWindowManager.IsWindowVisible(fWindow);
  461.     
  462.     if (result != show)
  463.     {
  464.         if (show)
  465.             gWindowManager.ShowWindow(fWindow);
  466.         else
  467.             gWindowManager.HideWindow(fWindow);
  468.     }
  469.     
  470.     return result;
  471. }
  472.  
  473.  
  474. //--------------------------------------------------------------------------------
  475. // by default windows can be closed, override if your window has a different policy
  476. Boolean TWindow::CanClose(void)
  477. {
  478.     return true;
  479. }
  480.  
  481.  
  482. //--------------------------------------------------------------------------------
  483. Boolean TWindow::Close(DescType /*saveOptions*/)
  484. {
  485.     this->Deactivate();
  486.     this->Dispose();
  487.     return true;
  488. }
  489.  
  490.  
  491. //--------------------------------------------------------------------------------
  492. Boolean TWindow::DeleteAfterClose(void)
  493. {
  494.     return true;
  495. }
  496.  
  497.     
  498. //--------------------------------------------------------------------------------
  499. // by default do nothing
  500. void TWindow::AdjustMenus(void)
  501. {
  502. }
  503.  
  504.  
  505. //--------------------------------------------------------------------------------
  506. //    By default, we just convert to local coordinates and call the window’s Click method.
  507. void TWindow::ClickAndDrag(EventRecord * anEvent)
  508. {
  509.     GlobalToLocal(&anEvent->where);
  510.     this->Click(anEvent);
  511. }
  512.  
  513.  
  514. //--------------------------------------------------------------------------------
  515. OSErr TWindow::HandleDrag(DragTrackingMessage dragMessage,DragReference theDrag)
  516. {
  517.     OSErr    result = dragNotAcceptedErr;
  518.     
  519.     switch (dragMessage)
  520.     {
  521.     case dragTrackingEnterWindow:
  522.         result = this->DragEnterWindow(theDrag);
  523.         break;
  524.     
  525.     case dragTrackingInWindow:
  526.         result = this->DragInWindow(theDrag);
  527.         break;
  528.         
  529.     case dragTrackingLeaveWindow:
  530.         result = this->DragLeaveWindow(theDrag);
  531.         break;
  532.         
  533.     default:
  534.         break;
  535.     }
  536.  
  537.     return result;
  538. }
  539.  
  540.  
  541. //--------------------------------------------------------------------------------
  542. OSErr TWindow::DragEnterWindow(DragReference /* theDrag */)
  543. {
  544.     return dragNotAcceptedErr;
  545. }
  546.  
  547.  
  548. //--------------------------------------------------------------------------------
  549. OSErr TWindow::DragInWindow(DragReference /* theDrag */)
  550. {
  551.     return dragNotAcceptedErr;
  552. }
  553.  
  554.  
  555. //--------------------------------------------------------------------------------
  556. OSErr TWindow::DragLeaveWindow(DragReference /* theDrag */)
  557. {
  558.     return dragNotAcceptedErr;
  559. }
  560.     
  561.  
  562. //--------------------------------------------------------------------------------
  563. OSErr TWindow::HandleDrop(DragReference /* theDrag */)
  564. {
  565.     return dragNotAcceptedErr;
  566. }
  567.  
  568.  
  569. Boolean    TWindow::IsPointInContentRgn( Point pt )
  570. {
  571.     return gWindowManager.PointInContentRgn(fWindow, pt);
  572. }
  573.  
  574. Rect TWindow::GetContentsBounds(void)
  575. {
  576.     return gWindowManager.GetWindowContentBounds(fWindow);
  577. }
  578.  
  579. //--------------------------------------------------------------------------------
  580. Boolean    TWindow::IsMouseInContentRgn( DragReference dragRef )
  581. {
  582.     Point    globalMouse;
  583.     OSErr    err;
  584.     
  585.     err = GetDragMouse( dragRef, &globalMouse, 0L );
  586.     
  587.     if ( err == noErr )
  588.         return( gWindowManager.PointInContentRgn(fWindow, globalMouse));
  589.     else
  590.         return( false );
  591. }
  592.  
  593.  
  594. //--------------------------------------------------------------------------------
  595. //    TWindowEventDispatcher overrides
  596. //--------------------------------------------------------------------------------
  597.  
  598. //--------------------------------------------------------------------------------
  599. Boolean TWindow::DispatchContentClick(EventRecord& event, WindowRef window)
  600. {
  601.     if (fWindow == window)
  602.     {
  603.         GrafPtr    oldPort;
  604.         GetPort(&oldPort);
  605.         SetPort((GrafPtr) window);
  606.         GlobalToLocal(&event.where);
  607.         this->Click(&event);
  608.         SetPort((GrafPtr) window);
  609.         return true;
  610.     }
  611.     else
  612.     {
  613.         // the click is in a window that is not activated
  614.         TWindow* win = TWindow::GetWindowObject(window);
  615.         
  616.         if (win)
  617.             win->Select();
  618.         else
  619.             SelectWindow(window);    /// TO DO: Fix this for floating windows
  620.         
  621.         return false;
  622.     }    
  623. }
  624.  
  625.  
  626. //--------------------------------------------------------------------------------
  627. Boolean TWindow::DispatchUpdate(EventRecord& event)
  628. {
  629.     WindowRef    w = (WindowRef) event.message;
  630.     GrafPtr        p = (GrafPtr) GetWindowPort(w);
  631.     GrafPtr        oldPort;
  632.  
  633. #if qDebug
  634. //    DebugStr("\pDropped update event");
  635. #endif
  636.     
  637.     GetPort(&oldPort);
  638.     SetPortWindowPort(w);
  639.     BeginUpdate(w);
  640.     
  641.     TWindow* win = TWindow::GetWindowObject(w);
  642.     
  643.     if (win)
  644.         win->Draw();
  645.     else
  646.         EraseRect(&p->portRect);
  647.         
  648.     EndUpdate(w);
  649.     SetPort(oldPort);
  650.     
  651.     return true;
  652. }
  653.  
  654.  
  655. //--------------------------------------------------------------------------------
  656. Boolean TWindow::DispatchActivateOrResume(EventRecord& /*event*/)
  657. {
  658.     this->Activate();
  659.     
  660.     return true;
  661. }
  662.  
  663.  
  664. //--------------------------------------------------------------------------------
  665. Boolean TWindow::DispatchDeactivateOrSuspend(EventRecord& /*event*/)
  666. {
  667.     this->Deactivate();
  668.     
  669.     return true;
  670. }
  671.  
  672.  
  673. //--------------------------------------------------------------------------------
  674. /// Caution Experimental Function
  675. //--------------------------------------------------------------------------------
  676. void RecordWindowBounds (long winIndex, Rect bounds);
  677. void RecordWindowBounds (long winIndex, Rect bounds)
  678. {
  679.     CAppleEvent event, reply;
  680.     CAETempDesc    windowObject, theData, theProperty, positionDesc, objectToSet, nullDesc;
  681.  
  682.     //  " set pBounds of window winIndex of app to bounds"
  683.  
  684.     // descripter for data value
  685.     theData.MakeRect(bounds);
  686.  
  687.     // descriptor for pIsZoomed
  688.     theProperty.MakeDescType(pBounds);
  689.  
  690.     // descriptor for the window object
  691.     FailOSErr(::CreateOffsetDescriptor(winIndex, (AEDesc *) &positionDesc));
  692.     
  693.     nullDesc.MakeNull();    
  694.     FailOSErr(::CreateObjSpecifier(cWindow, (AEDesc *) &nullDesc, formAbsolutePosition, 
  695.                     (AEDesc *) &positionDesc, false, (AEDesc *) &windowObject));
  696.  
  697.     FailOSErr(::CreateObjSpecifier(cProperty, (AEDesc *) &windowObject, formPropertyID,
  698.                     (AEDesc *) &theProperty, false, (AEDesc *) &objectToSet));
  699.  
  700.     // let it rip
  701.             // generate a SetData event
  702.     FailOSErr(::AECreateAppleEvent(kAECoreSuite, kAESetData, &TApplication::fgCurrentProcessDesc,
  703.                     kAutoGenerateReturnID, kAnyTransactionID, (AEDesc *) &event));
  704.             //    Attach the property object specifier.
  705.     FailOSErr(::AEPutParamDesc((AEDesc *) &event, keyDirectObject, (AEDesc *) &objectToSet));
  706.             //    Add the property data.
  707.     FailOSErr(::AEPutParamDesc((AEDesc *) &event, keyAEData, (AEDesc *) &theData));
  708.             //  Send it for rcording purposes only
  709.       FailOSErr(::AESend((AEDesc *) &event, (AEDesc *) &reply, kAENoReply+kAECanInteract+kAEDontExecute,
  710.                       kAENormalPriority, kAEDefaultTimeout, nil, nil));
  711.     
  712.     // Deallocate stuff ??
  713. }
  714.  
  715. //--------------------------------------------------------------------------------
  716. Boolean TWindow::TrackDrag(EventRecord& event, WindowRef window)
  717. {
  718.     TWindowEventDispatcher::TrackDrag(event, window);
  719.     // record the new window size in an Apple Event - SHOULD RECORD POSITION INSTEAD
  720.     RecordWindowBounds(this->GetIndex(), this->GetBounds());
  721.     return true;
  722. }
  723.  
  724.  
  725. //--------------------------------------------------------------------------------
  726. // mouse down in the grow box, deal with the event here
  727. Point TWindow::TrackGrow(EventRecord& event, WindowRef window)
  728. {
  729.     Point newSize = TWindowEventDispatcher::TrackGrow(event, window);
  730.  
  731.     ::SizeWindow(fWindow, newSize.h, newSize.v, true);
  732.     // record the new window size in an Apple Event
  733.     RecordWindowBounds(this->GetIndex(), this->GetBounds());
  734.     return newSize;
  735. }
  736.  
  737.  
  738. //--------------------------------------------------------------------------------
  739. // mouse down in the close box, deal with the event here
  740. Boolean TWindow::TrackGoAway(EventRecord& event, WindowRef window)
  741. {
  742.     if (TWindowEventDispatcher::TrackGoAway(event, window))
  743.         Close();
  744.     return true;
  745. }
  746.  
  747. //--------------------------------------------------------------------------------
  748. /// Caution Experimental Function
  749. //--------------------------------------------------------------------------------
  750. void PostSetDataToTWin_Zoomed (Boolean flag);
  751. void PostSetDataToTWin_Zoomed (Boolean flag)
  752. {
  753.     CAppleEvent event, reply;
  754.     CAETempDesc    windowObject, theData, theProperty, positionDesc, objectToSet, nullDesc;
  755.  
  756.     //  " set pIsZoomed of window 1 of app to flag"
  757.  
  758.     // descripter for data value
  759.     theData.MakeBoolean(flag);
  760.  
  761.     // descriptor for pIsZoomed
  762.     theProperty.MakeDescType(pIsZoomed);
  763.  
  764.     // descriptor for the window object
  765.     long        index = 1;        // for now it is always the front window
  766.     
  767.     FailOSErr(::CreateOffsetDescriptor(index, (AEDesc *) &positionDesc));
  768.     
  769.     nullDesc.MakeNull();    
  770.     FailOSErr(::CreateObjSpecifier(cWindow, (AEDesc *) &nullDesc, formAbsolutePosition, 
  771.                     (AEDesc *) &positionDesc, false, (AEDesc *) &windowObject));
  772.  
  773.     FailOSErr(::CreateObjSpecifier(cProperty, (AEDesc *) &windowObject, formPropertyID,
  774.                     (AEDesc *) &theProperty, false, (AEDesc *) &objectToSet));
  775.  
  776.     // let it rip
  777.             // generate a SetData event
  778.     FailOSErr(::AECreateAppleEvent(kAECoreSuite, kAESetData, &TApplication::fgCurrentProcessDesc,
  779.                     kAutoGenerateReturnID, kAnyTransactionID, (AEDesc *) &event));
  780.             //    Attach the property object specifier.
  781.     FailOSErr(::AEPutParamDesc((AEDesc *) &event, keyDirectObject, (AEDesc *) &objectToSet));
  782.             //    Add the property data.
  783.     FailOSErr(::AEPutParamDesc((AEDesc *) &event, keyAEData, (AEDesc *) &theData));
  784.             //  Send it
  785.       FailOSErr(::AESend((AEDesc *) &event, (AEDesc *) &reply, kAENoReply, kAENormalPriority,
  786.                       kAEDefaultTimeout, nil, nil));
  787.     
  788.     // Deallocate stuff ??
  789. }
  790.  
  791. //--------------------------------------------------------------------------------
  792. Boolean TWindow::TrackZoomIn(EventRecord& event, WindowRef window)
  793. {
  794.     if (TWindowEventDispatcher::TrackZoomIn(event, window))
  795.         PostSetDataToTWin_Zoomed(false);
  796. //        TWindow::ZoomWindow(fWindow, inZoomIn, this->GetPerfectWindowSize());
  797.     return true;
  798. }
  799.  
  800.  
  801. //--------------------------------------------------------------------------------
  802. Boolean TWindow::TrackZoomOut(EventRecord& event, WindowRef window)
  803. {
  804.     if (TWindowEventDispatcher::TrackZoomOut(event, window))
  805.         PostSetDataToTWin_Zoomed(true);
  806. //        TWindow::ZoomWindow(fWindow, inZoomOut, this->GetPerfectWindowSize());
  807.     return true;
  808. }
  809.  
  810. //--------------------------------------------------------------------------------
  811. void TWindow::AEGetNameDesc(CAEDesc& value, const CAETypeList& /*requestedTypes*/) const
  812. {
  813.     Str255  title;
  814.     
  815.     ::GetWTitle(fWindow, title);
  816.     value.MakeString(title);
  817. }
  818.  
  819.  
  820. //--------------------------------------------------------------------------------
  821. void TWindow::AESetNameDesc(const CAEDesc& name)
  822. {
  823.     Str255 title;
  824.     
  825.     name.GetString(title);
  826.     
  827.     ::SetWTitle(fWindow, title);
  828. }
  829.  
  830. //--------------------------------------------------------------------------------
  831. // this window has gotten an AEClose event, execute it here
  832. void TWindow::HandleAEClose(AEServerEvent& /*event*/)
  833. {
  834.     /// we should look at the event to see if there are optional arguments, but for now ...
  835.     
  836.     // just do it
  837.     if (this->CanClose())
  838.         this->Close();
  839.     else
  840.         Fail(errAEEventNotHandled);
  841. }
  842.  
  843. //--------------------------------------------------------------------------------
  844. //    Utility Functions used for floating windows
  845. //--------------------------------------------------------------------------------
  846.  
  847. //--------------------------------------------------------------------------------
  848.     
  849.  
  850. TWindow* TWindow::GetWindowObject(WindowRef aWindow)
  851. {
  852.     TWindow*    result = nil;
  853.     short        wKind;
  854.     
  855.     if (aWindow != nil)
  856.     {
  857.         wKind = GetWindowKind ( aWindow );
  858.  
  859.         if (wKind >= userKind)
  860.         {
  861.             //    All windowKinds >= userKind are based upon TWindow
  862.             result = (TWindow *) GetWRefCon(aWindow);
  863.         }
  864.     }    
  865.     return result;
  866. }
  867.  
  868.  
  869. //--------------------------------------------------------------------------------
  870. TWindow* TWindow::GetNthWindow(long index, WindowLayer layer)
  871. {
  872.     return TWindow::GetWindowObject(gWindowManager.GetNthWindow(index, layer));
  873. }
  874.  
  875.  
  876. //--------------------------------------------------------------------------------
  877. // find any type of window with the input name
  878. TWindow* TWindow::GetNamedWindow(ConstStr255Param name, WindowLayer layer)
  879. {
  880.     return TWindow::GetWindowObject(gWindowManager.GetNamedWindow(name, layer));
  881. }
  882.  
  883.  
  884. //--------------------------------------------------------------------------------
  885. //    Drag Manager callback routines which dispatch to a window’s method
  886. //--------------------------------------------------------------------------------
  887.  
  888. pascal OSErr TWindow::CallWindowDragTrackingHandler(DragTrackingMessage dragMessage,
  889.                             WindowRef theWindow, void * /* refCon */,DragReference theDrag)
  890. {
  891.     TWindow *wobj = TWindow::GetWindowObject(theWindow);
  892.     
  893.     if (wobj)
  894.         return(wobj->HandleDrag(dragMessage,theDrag));
  895.     else
  896.         return dragNotAcceptedErr;
  897. }
  898.  
  899. pascal OSErr TWindow::CallWindowDragReceiveHandler(WindowRef theWindow, void * /* refCon */,
  900.                                             DragReference theDrag)
  901. {
  902.     TWindow *wobj = TWindow::GetWindowObject(theWindow);
  903.     
  904.     if (wobj)
  905.         return(wobj->HandleDrop(theDrag));
  906.     else
  907.         return dragNotAcceptedErr;
  908. }
  909.  
  910.  
  911.